﻿using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.Configuration;
using VOL.Core.Extensions;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Threading;
using System.Collections.Concurrent;
using Microsoft.Extensions.Caching.Memory;
using System.Runtime.CompilerServices;


namespace VOL.Core.Utilities
{
    public static class MQHelper
    {
       
        private static string hostName { get; set; }
        private static string userName { get; set; }
        private static string password { get; set; }
        private static int port;

        static MQHelper() {
            IConfigurationSection section = AppSetting.GetSection("MQ");
             hostName = section["HostName"];
             userName = section["UserName"];
             password = section["Password"];
             port =(int)section["Port"].ToInt32();
        }
        /// <summary>
        /// MQ发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <param name="queue"></param>
        public static void MQSendMsg(string message, string queue = "hello")
        {//http://192.168.110.183:15672/

            // 创建连接工厂对象
            var factory = new ConnectionFactory()
            {
                HostName = hostName, // 主机名
                Port = port, // 端口号
                UserName = userName, // 用户名
                Password = password// 密码
            };

            // 创建连接对象
            using (var connection = factory.CreateConnection())
            {
                // 创建通道对象
                using (var channel = connection.CreateModel())
                {
                    // 声明一个队列
                    channel.QueueDeclare(
                        queue: queue, // 队列名
                        durable: false, // 是否持久化
                        exclusive: false, // 是否排他
                        autoDelete: false, // 是否自动删除
                        arguments: null // 其他参数
                    );

                    // 定义要发送的消息内容
                    var body = Encoding.UTF8.GetBytes(message);

                    // 发送消息到队列
                    channel.BasicPublish(
                        exchange: "", // 交换机名，空字符串表示默认交换机
                        routingKey: queue, // 路由键，即队列名
                        basicProperties: null, // 消息属性，如持久化、优先级等
                        body: body // 消息体
                    );

                    Console.WriteLine(" [x] Sent {0}", message);
                }
            }

            Console.WriteLine(" Press [enter] to exit.");

        }
        private static void CacheMessage(string message,ConcurrentQueue<string> _messageQueue)
        {
            // 使用消息内容作为缓存键（或者你可以使用其他唯一标识符）
          //  var cacheKey = message;

         //   // 将消息缓存起来，设置一个过期时间（例如1小时）
         //   _cacheNew.Set(cacheKey, message, TimeSpan.FromHours(1));
        //    var s = _cacheNew.Get(cacheKey);
            // 将消息添加到队列中
            _messageQueue.Enqueue(message);
            Console.WriteLine($"Message '{message}' has been cached.");
        }
        /// <summary>
        /// MQ接收
        /// </summary>
        /// <param name="message"></param>
        /// <param name="queue"></param>
        public static void MQReceived( string queue, ConcurrentQueue<string> _messageQueue)
        {


            string rs = string.Empty;
            // 创建连接工厂对象
            var factory = new ConnectionFactory()
            {
                HostName = hostName, // 主机名
                Port = port, // 端口号
                UserName = userName, // 用户名
                Password = password// 密码
            };

            // 创建连接对象
            using (var connection = factory.CreateConnection())
            {
             //   ConcurrentBag<string> mesList = new ConcurrentBag<string>();
                // 或使用锁机制
                object lockObj = new object();
                //  var mesList=new List<string>();
                // 创建通道对象
                using (var channel = connection.CreateModel())
                {
                    // 声明一个队列，如果队列不存在则创建，如果存在则不影响
                    channel.QueueDeclare(
                        queue: queue, // 队列名
                        durable: false, // 是否持久化
                        exclusive: false, // 是否排他
                        autoDelete: false, // 是否自动删除
                        arguments: null // 其他参数
                    );

                    // 定义一个消费者对象，用于接收消息并处理
                    var consumer = new EventingBasicConsumer(channel);
                    // AutoResetEvent autoEvent = new AutoResetEvent(false);
                    ManualResetEvent autoEvent = new ManualResetEvent(false);
                    Thread thread = new Thread(() =>
                    {
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body.ToArray();
                            var message = Encoding.UTF8.GetString(body);
                            CacheMessage(message, _messageQueue);
                         //   lock (lockObj) { mesList.Add(message); }

                            Console.WriteLine(" [x] Received {0}", message);
                            Thread.Sleep(200);
                            autoEvent.Set();
                        };
                    });
                    thread.Start();
                //    autoEvent.WaitOne(1000);

               //     messagelist = mesList;
                    // 启动消费者，设置为手动应答模式（autoAck=false）
                    channel.BasicConsume(
                        queue: queue, // 队列名
                        autoAck: true, // 是否自动应答，false表示手动应答，需要调用BasicAck方法确认消息已处理完成，否则会导致消息堆积或重复消费；true表示自动应答，一旦接收到消息就认为已处理完成，无需确认。
                        consumer: consumer);  // 消费者对象
                 //   messagelist = mesList;

                    Console.WriteLine(" Press [enter] to exit.");
                    Console.ReadLine();

                }
            }
        }
        
        /// <summary>
        /// MQ接收
        /// </summary>
        /// <param name="message"></param>
        /// <param name="queue"></param>
        public static void MQReceived(out ConcurrentBag<string> messagelist, string queue, ConcurrentQueue<string> _messageQueue)
        {

           
            string rs = string.Empty;
            // 创建连接工厂对象
            var factory = new ConnectionFactory()
            {
                HostName = hostName, // 主机名
                Port = port, // 端口号
                UserName = userName, // 用户名
                Password = password// 密码
            };

            // 创建连接对象
            using (var connection = factory.CreateConnection())
            {
                 ConcurrentBag<string> mesList = new ConcurrentBag<string>();
                // 或使用锁机制
                 object lockObj = new object();
      //  var mesList=new List<string>();
                // 创建通道对象
                using (var channel = connection.CreateModel())
                {
                    // 声明一个队列，如果队列不存在则创建，如果存在则不影响
                    channel.QueueDeclare(
                        queue: queue, // 队列名
                        durable: false, // 是否持久化
                        exclusive: false, // 是否排他
                        autoDelete: false, // 是否自动删除
                        arguments: null // 其他参数
                    );

                    // 定义一个消费者对象，用于接收消息并处理
                    var consumer = new EventingBasicConsumer(channel);
                    // AutoResetEvent autoEvent = new AutoResetEvent(false);
                    ManualResetEvent autoEvent = new ManualResetEvent(false);
                    Thread thread=new Thread (()=> {
                        consumer.Received += (model, ea) =>
                        {
                            var body = ea.Body.ToArray();
                            var message = Encoding.UTF8.GetString(body);
                            CacheMessage(message, _messageQueue);
                            lock (lockObj) { mesList.Add(message); }
                
                            Console.WriteLine(" [x] Received {0}", message);
                            Thread.Sleep(200);
                            autoEvent.Set();
                        };
                    });
                    thread.Start();
                    autoEvent.WaitOne(1000);
                  
                    messagelist = mesList;
                    // 启动消费者，设置为手动应答模式（autoAck=false）
                    channel.BasicConsume(
                        queue: queue, // 队列名
                        autoAck: true, // 是否自动应答，false表示手动应答，需要调用BasicAck方法确认消息已处理完成，否则会导致消息堆积或重复消费；true表示自动应答，一旦接收到消息就认为已处理完成，无需确认。
                        consumer: consumer);  // 消费者对象
                    messagelist = mesList;
         
                    Console.WriteLine(" Press [enter] to exit.");
                    Console.ReadLine();
                
                }
            }
        }
       
    }
}
